1. The Field of the Invention
This invention relates to systems and methods for freeing shared resources in a computer system, More specifically, the present invention relates to systems and methods for freeing shared resources that have been allocated to a process that has terminated without freeing resources allocated to it
2. Background of the Invention
When personal computers were first introduced, the operating systems were fairly rudimentary and only provided for a single task or process to run on the computer at any given time. This process had complete access to all system resources when it was running and could generally directly access any of the hardware devices on the computer. For example, many processes wrote directly to the display hardware to display information to a user. Because the process was the only process trying to access the display device, writing directly to the display device produced few problems and generally resulted in good performance even though these early personal computers had relatively little computing power.
One unfortunate drawback of directly accessing the computer hardware is that the program expected to see a particular type of hardware. This typically did not create any problems as long as most computers had identical hardware. For example, early computers offered very few choices with regards to the type of display device. As technology increased, however, the types of display devices available have proliferated and users today seem to have an almost limitless choice of display devices. If a process is going to write directly to the display device, the process must be able to operate with many, if not all, of the various display devices that are available This can create enormous problems for computer programs that are created for wide distribution. Display devices are not the only hardware devices where these types of problems can arise. Other computer hardware may also present similar problems if a program attempts to directly access the hardware.
In order to eliminate the direct dependence on hardware, methods have been developed to allow a process to access a piece of hardware in a "device independent" manner, Essentially, this means that a process can access a particular type of hardware device in a manner that is essentially consistent from one hardware device to another. For example, if a program is to access a display device it would be desirable to allow the program to access any type of display device in substantially the same manner without having to worry about the particular hardware details of each individual display device. In order to provide a consistent interface between a process and a particular type of hardware device, there may be several abstraction layers between the actual hardware and the process. FIG. 1 contains an illustration of one method for allowing a process device independent access to hardware.
In FIG. 1, the actual hardware is illustrated by hardware 10. This hardware is often referred to as a "hardware layer." Hardware 10 represents the actual system hardware itself, such as a display device with its accompanying adapter card or a disk drive controller. On top of the hardware layer is often a "driver layer." In FIG. 1, the driver layer is illustrated by hardware driver 12. The driver layer is typically responsible for interfacing directly with the hardware and provides a set of interface functions that allow low level access to hardware 10. The driver layer hides device details by taking device independent requests and converting them to hardware specific requests. In other words, the driver layer provides a standardized or consistent set of functions that allows access to a particular type of hardware device in a substantially consistent manner independent of the actual hardware device used. Interfacing with hardware driver 12 is an application program interface layer or "API layer." The API layer enhances the ease of use of the driver layer, The API layer can provide parameter validation and error checking to filter bad requests from processes. The API layer may also implement higher level services on top of the driver layer in order to add additional functionality. In FIG. 1, the API layer is illustrated by application program interface 14. As illustrated in FIG. 1, process 16 uses application program interface 14 to access hardware 10 through hardware driver 12. Together, hardware driver 12 and application program interface 14 allow process 16 to access hardware 10 in a device independent manner so that the hardware details are hidden and the interface remains substantially constant independent of the actual hardware used.
Accessing hardware in a device independent manner overcomes the drawback of requiring a process to be written specifically for a particular type of hardware and allows a single process to function with a wide variety of hardware devices. Another problem that has arisen due to advances in technology is the need to share single hardware devices among a plurality of processes. In the early days of personal computers, the hardware and operating systems were designed to allow a single process to run on the computer at any given moment. However, today's operating systems often allow several processes to appear to run simultaneously on a single computer. This capability, known as multitasking, requires multiple processes on a single computer to share common hardware. For example, for computer systems that have only a single display device, if two processes are running simultaneously on the computer, then each may need access to the display device. This creates a situation where the display device must be shared among multiple processes. Similar requirements exist for other types of computer hardware such as input devices like keyboards, a mouse or other pointing device, or another type of input device, mass storage devices such as disk drives, and other hardware that may need to be shared among multiple processes.
To accommodate such shared access to various hardware devices while maintaining device independent access to hardware, the model presented in FIG. 1 can be extended. For example, hardware layer 10 can become a shared hardware device. Hardware driver 12 may become a shared hardware driver, and application program interface 14 may become a shared application program interface. Referring now to FIG. 2, these three layers are illustrated as shared hardware layer 16, shared hardware driver layer 18, and shared API layer 20. As indicated in FIG. 2, these layers are shared among a plurality of processes. For example, shared hardware layer 16 may represent a common display device that is shared by multiple processes. Shared hardware layer 16 is accessed through shared hardware driver layer 18 which, like its counterpart in FIG. 1, generally provides a set of functions that allows low level access to shared hardware layer 16 Finally, shared API layer 20 provides a device independent interface for the multiple processes that share the hardware.
In FIG. 2, the hardware is shared by two processes, process A, indicated generally as 22 and process B, indicated generally as 24. Since shared API layer 20, shared hardware driver layer 18, and shared hardware layer 16 must be shared between a plurality of processes, such as process 22 and process 24, it may be desirable to map shared API layer 20, shared hardware driver layer 18, and shared hardware layer 16 into the address space of both process 22 and process 24. This is indicated in FIG. 2 by showing shared API layer 20, shared hardware driver layer 18, and shared hardware layer 16 as part of the shared address space. Anything in the shared address space is literally shared between both processes. For example, shared API layer 20 can be seen and accessed both by process 22 and process 24. This is because shared API layer 20, as well as the other shared layers, are mapped into the address space of the processes and become part of the processes. Because shared API layer 20 is shared between a plurality of processes, the shared API layer must be able to resolve conflicts and contentions between the plurality of processes. In general, shared API libraries are quite complex and take a lot of time and care to develop.
In addition to the shared address space, each individual process typically has a local or nonshared address space The local address space contains the local executable code and data of the process. In addition, local API layers, such as local API layer 26, may also be loaded into the local address space of a process. In summary, a process may consist of local executable code and data, local API layers, shared API layers, shared hardware drivers, and shared hardware.
When a hardware device is shared among a plurality of processes, it may be necessary to allocate certain resources for use specifically by a particular process. For example, when a display device is shared among a plurality of processes, each process may require allocation of some video memory of the display device. This allows the process to write data into the video memory in order to display information on the display device. Conceptually, the allocated resources can be viewed as being allocated in the shared API layer, since that is the layer that a process will use to access the hardware in a device independent manner. In FIG. 2, such shared resources are illustrated by shared resource 28, shared resource 30, and shared resource 32. In FIG. 2, shared resource 28 and shared resource 30 are allocated for use by process A as indicated by the "A" label. Shared resource 32 is allocated for use by process B as indicated by the "B" label.
In addition to the resources allocated in the shared API layer, certain shared hardware driver layers may also keep information internally that relates specifically to a particular process. For example, in FIG. 2, shared hardware driver 18 has resource 34 that relates specifically to process A. Resources in the shared hardware driver layer 18 may be linked to or related to resources allocated in shared API layer 20 as indicated by line 36. Resource 34 can be any type of resource that is needed to be kept specifically for a particular process. For example, resource 34 can be internal representation of data that is stored for process A in resource 28 of shared API layer 20.
In addition to resources allocated in a shared API layer, if a process has a local API layer loaded into its local address space, such as local API layer 26, then resources may also be allocated in the local API layer. This is illustrated in FIG. 2 by resource 38 of local API layer 26. Such resources can be any type of resource that is allocated by a particular process through the local API layer.
One problem with allocating resources in shared layers is that such resources tend to be scarce. For example, display devices typically only have a limited amount of video memory that can be allocated for use. The limited amount of video, memory must be shared among all processes. Thus, if one process allocates a large amount of video memory and then does not return the video memory to a pool where it can be allocated for use by another process, a situation can arise where there is insufficient video memory to allow a particular process to run successfully. Thus, it is very important that a process properly return allocated resources to a state where they can be reallocated for use by another process. In FIG. 2, if process A terminated without releasing the resources allocated in shared API layer 20 and shared hardware driver layer 18, these resources would remain allocated for use by the process, even though the process had terminated. In general, it is very difficult for a shared layer to determine when a resource is no longer needed by a particular process is without input by the process. If the process has terminated abruptly, the process may leave resources allocated.
In order to avoid resource "leaks" when a process terminates abruptly and leaves resources in a shared layer allocated, one approach has employed a specialized second process specifically adapted.1 to free shared resources. This second process can call a function in the shared layer that allows the shared layer to release allocated resources that are no longer needed and return them to a shared pool where they can be reallocated for use by another process. Such a situation is illustrated in FIG. 3. In FIG. 3, process 22 has terminated leaving resources in shared API layer 20 and shared hardware driver layer 18 allocated. Assuming process 24 is a specialized cleanup process, when process 24 discovers that process 22 has terminated, process 24 may call a cleanup function in shared API layer 20, such as cleanup 40. Cleanup function 40 can release resource 28 and resource 30 in shared API layer 20. Additionally, this process may also call a function in shared hardware driver 18 to release resource 34. If resource 28 is a software object, then resource 28 may be freed by calling a function or method of the object which destroys the object. The method that destroys the object may also call other methods in other objects or otherwise make system calls to free allocated resources, In this way, resources in the shared layers that remain allocated after a process terminates can be freed by another process that continues to run.
As indicated in FIG. 3, when process 22 terminates, all information in the local address space is destroyed and the resources allocated to the local address space of the process are returned to the system. This is part of the automatic cleanup of local resources that is performed by the operating system when a process terminates. Thus, when process 22 terminates, resource 38 of local API layer 26 is freed and returned to the shared pool of resources. The operating system cannot free shared resources because it has no knowledge of the binding between a process and a shared resource allocated in a shared API layer or shared driver layer. To release the shared resources another approach, such as employing process 24 to free shared resources must be used. Thus, the combination of process 24 calling cleanup function 40 to release resources allocated in the shared layers and the termination of process 22 itself, returned all allocated resources to a state where they could be reallocated for use by another process. The described method works quite well for resources that are contained in local API layers and resources that are contained in shared layers. However, if the resources in the shared layers are linked to the resources in the local layers, then the above method will not work. This is because when process 22 terminates and local resources are released, the links between resources allocated in the shared layers and the local layers would remain intact and be pointing to an undefined location after process 22 terminated. If any attempt was made by an allocated resource in a shared layer to follow the link to another resource that needed to be released, unpredictable results would occur. Furthermore, if resources allocated in a local API layer, such as resource 38 of local API layer 26, were linked to resources in shared hardware driver layer 18, then there would be no way to follow the link to properly release the resources in the shared hardware driver layer.
Thus, what is needed is a way to release shared resources that have links to resources that are not shared. In addition, it would be desirable to provide a system and method to release resources in a shared driver layer that were allocated by, and linked to, resources allocated in a local API layer.